/*
 * OrganizadorTextos.cpp
 *
 *  Created on: 21/05/2013
 *      Author: jonathan
 */


#include "OrganizadorTextos.h"
#include "../general/estructuras/Documento.h"
#include "../general/estructuras/Termino.h"
#include "../parsing/Parseado.h"
#include "../parsing/ParserDocumento.h"
#include "../preproceso/estructuras/EntradaAuxiliar.h"
#include "../preproceso/archivos/ArchivoAuxiliar.h"
#include "../preproceso/estructuras/EntradaDocumento.h"
#include "../preproceso/archivos/ArchivoDocumentos.h"
#include <sstream>
#include <map>
#include <string>
#include <iostream>
using namespace std;

OrganizadorTextos::OrganizadorTextos(FileName entrada, FileName salida,
		FileName prefijo, FileName extension, FileName nombreRepo) {
	this->salida = salida;
	this->extensionSalida = extension;
	this->entrada = entrada;
	this->prefijoSalida = prefijo;
	this->nombreRepo = nombreRepo;
}

OrganizadorTextos::~OrganizadorTextos() {
	// TODO Auto-generated destructor stub
}


//TODO DEBERIA DEVOLVER LA LISTA DE DOCUMENTO - NRO
EnteroLargo OrganizadorTextos::procesar() {
	list<FileName>::iterator it;
	Parseado elemento("",0);
	Termino * termino;
	Documento * documento;
	EnteroLargo nroDoc = 0;
	string filename;
	FileList archivos(this->entrada, "txt");
	EnteroLargo contador =0;

	EntradaDocumento* entDoc;
	ArchivoDocumentos* archDoc = new ArchivoDocumentos(this->nombreRepo,this->salida.c_str(),
                                                    ios_base::out);
	list<EntradaDocumento> listadocs;

	while (archivos.hasNext()) {

		filename = archivos.next();
		//		cout << "el archivo que abrio es " << filename << endl;
        entDoc = new EntradaDocumento(nroDoc,filename);
        listadocs.push_back(*entDoc);
		contador++;
		//se crean las variables y se destruyen en cada iteracion.
		ParserDocumento p(filename.c_str());
		map<std::string, Termino*> mapa;
		map<std::string, Termino*>::iterator posicionTermino;
		while (p.hasNext()) {
			elemento = p.next();
			posicionTermino = mapa.find(elemento.getTermino());
			if (posicionTermino != mapa.end()) {
				termino = posicionTermino->second;
				termino->getDocumentos()->front()->getPosiciones()->push_back(
						elemento.getPosicion());
			} else {//cuando itere para sacarlos los voy a ir borrando tambien.
				documento = new Documento();
				documento->setNumero(nroDoc);
				documento->addPosicion(elemento.getPosicion());
				termino = new Termino();
				termino->setCaracteres(elemento.getTermino());
				termino->addDocumento(documento);
				mapa.insert(posicionTermino,std::pair<string, Termino*>(termino->getCaracteres(), termino));
			}
		}

		this->guardarEnArchivo(&mapa, this->armarNombreArchivo(nroDoc));
		nroDoc++;
	}

	archDoc->escribir(listadocs);

	cout<<"SE PROCESARON " << contador<< " ARCHIVOS" << endl;
	return contador;

}

//void OrganizadorTextos::obtenerArchivos(FileName entrada) {
//	//aca hay que usar alguna funcion que liste los archivos en vez de esto.
//	this->archivos.push_back("uno.txt");
//	this->archivos.push_back("dos.txt");
//	this->archivos.push_back("tres.txt");
//}
void OrganizadorTextos::guardarEnArchivo(map<std::string,Termino*>* mapa, string archivo){
//	cout<< archivo <<endl;
	std::map<std::string, Termino*>::iterator it;
	ArchivoAuxiliar aaux(archivo.c_str(), ios_base::out);
//	perror("creacion");
	//aca hay un tema de memoria? no lo se... mirar
	for (it = mapa->begin(); it != mapa->end(); ++it) {
//		cout<< it->first << endl;
//		cout<< "Posiciones :";
		list<EnteroLargo>::iterator it2;
		Termino * termino = it->second;
		Documento * doc = termino->getDocumentos()->front();
		EntradaAuxiliar entrada(termino->getCaracteres(), doc->getNumero());
		list<EnteroLargo> * enteros = doc->getPosiciones();
		for(it2= enteros->begin();it2!=enteros->end();++it2){
//			cout<< *it2 << ", ";
			entrada.addPosicion(*it2);
		}
		aaux.escribir(&entrada);
//		cout<< endl;
		// PARA LIBERAR MEMORIA
		delete  it->second;
	}
	aaux.close();
}

string OrganizadorTextos::armarNombreArchivo(EnteroLargo doc){
	string  fn;
	fn.append(this->salida );
	fn.append("/");
	fn.append(this->prefijoSalida);
	fn.append(to_string(doc));
	fn.append(".");
	fn.append(this->extensionSalida);
	return fn;
}
